﻿(function($) {

    $.addPgr = function(pgr, options) {
        var defaults = {
            gridId: '',     // Grid id (last part only, e.g. 'A')
            url: '',        // ajax url
            page: 1,        // current page
            pages: 1,       // total pages
            ps: 10,         // page size
            newp: 1,        //
            keepPs: false,  // add empty rows
            pagestat: 'Displaying {from} to {to} of {total}',
            singlepagestat: 'Displaying {from} of {total}',
            updateOpacity: 0.5,
            sort: '',
            order: 'ascending',
            query: ''
        };
        var p = $.extend(defaults, options);

        var tId = '#data' + p.gridId;

        var updateData = function(data, id) {
            var pId = '#' + id;

            // Remove the table data rows
            $(tId + ' table tbody tr').remove();

            // Count the data rows, and fill up missing with empty rows up to the page size
            var r = 0;

            // Build the new row HTML and add each row to the table 
            $.each(data.rows, function(entryIndex, entry) {
                var html = '<tr>';
                for (i = 0; i < p.colModel.length; i++) {
                    html += '<td>';
                    var val = entry[p.colModel[i].key];
                    if (p.colModel[i].format) {
                        var format = p.colModel[i].format;
                        val = format.replace(/\{0\}/g, entry[p.colModel[i].key]);
                        if (p.colModel[i].formatKey) {
                            val = val.replace(/\{1\}/g, entry[p.colModel[i].formatKey]);
                        }
                    }
                    html += val + '</td>';
                }
                html += '</tr>';
                $(tId + ' table tbody').append(html);
                r++;
            });

            if (p.keepPs) {
                for (i = r; i < p.ps; i++) {
                    $(tId + ' table tbody').append('<tr><td class="empty" colspan="' + p.colModel.length + '">&nbsp;</td></tr>');
                }
            }

            // Add zebra striping for the new rows through the defined CSS class.
            $(tId + ' table tbody tr:nth-child(even)').addClass("alt");

            // Update the current page number
            p.page = data.page;
            $(pId + 'PN:first').val(p.page);

            // Update the total number of pages
            p.pages = data.pages;
            $(pId + 'PC:first').text(p.pages);

            // Update the page stats
            var stat = p.pagestat;
            stat = stat.replace(/{from}/, data.from);
            stat = stat.replace(/{to}/, data.to);
            stat = stat.replace(/{total}/, data.total);
            $(pId + ' .tBtnST:first').text(stat);

            // Update the pager button state
            $(pId + ' .tBtnF:first').toggleClass('tBtnFd', !(p.page > 1));
            $(pId + ' .tBtnP:first').toggleClass('tBtnPd', !(p.page > 1));
            $(pId + ' .tBtnN:first').toggleClass('tBtnNd', !(p.page * p.ps < data.total));
            $(pId + ' .tBtnL:first').toggleClass('tBtnLd', !(p.page * p.ps < data.total));

            // Restore the reload button
            if (!$.browser.msie) { $(tId).fadeTo("fast", 1); }
            $(pId + ' .tBtnR:first').toggleClass('tBtnRL');
        } // end updateData()

        var changePage = function(ctype, id, val) {
            var pId = '#' + id;
            var getData = false;

            switch (ctype) {
                case 'first': p.newp = 1; break;
                case 'prev': if (p.page > 1) { p.newp = parseInt(p.page, 10) - 1; } break;
                case 'next': if (p.page < p.pages) { p.newp = parseInt(p.page, 10) + 1; } break;
                case 'last': p.newp = p.pages; break;
                case 'pn':
                    var nv = parseInt($(pId + 'PN:first').val(), 10);
                    if (isNaN(nv) || nv < 1) { nv = 1; }
                    if (nv > p.pages) { nv = p.pages; }
                    $(pId + 'PN:first').val(nv);
                    p.newp = nv;
                    break;
                case 'ppn':
                    if (val) {
                        var nv = parseInt(val, 10);
                        if (isNaN(nv) || nv < 1) { nv = 1; }
                        if (nv > p.pages) { nv = p.pages; }
                        $(pId + 'PN:first').val(nv);
                        p.newp = nv;
                    }
                    break;
                case 'ps': getData = true; p.ps = $(pId + 'PS:first').val(); break;
                case 'refresh': getData = true; break;
            }

            if (p.newp == p.page && !getData) { return false; }

            if (!p.newp) { p.newp = 1; }
            if (p.page > p.pages) { p.page = p.pages; }

            // Show loading image and dim the table
            $(pId + ' .tBtnR:first').toggleClass('tBtnRL');
            if (!$.browser.msie) { $(tId).fadeTo("fast", p.updateOpacity); }

            $.getJSON(p.url, { p: p.newp, ps: p.ps, sort: p.sort, order: p.order, q: p.query }, function(data) { updateData(data, id) });

        }   // end changePage()

        var id = pgr.id;

        // Hijax the pager controls, if Ajax requests are enabled
        $('#' + id + ' .tBtnF:first').click(function() { changePage('first', id); return false; });
        $('#' + id + ' .tBtnP:first').click(function() { changePage('prev', id); return false; });
        $('#' + id + ' .tBtnN:first').click(function() { changePage('next', id); return false; });
        $('#' + id + ' .tBtnL:first').click(function() { changePage('last', id); return false; });
        $('#' + id + 'PN:first').keydown(function(e) { if (e.keyCode == 13) { changePage('pn', id); } });
        $('#' + id + 'PS:first').change(function() { changePage('ps', id) });
        $('#' + id + ' .tBtnR:first').click(function() { changePage('refresh', id); return false; });

        pgr.options = p;
        return pgr;
    }

    $.fn.pagerOptions = function(options) { //function to update general options
        return this.each(function() {
            if (this.options) {
                $.extend(this.options, options);
            }
        });
    };

    $.fn.pager = function(options) {
        return this.each(function() {
            $.addPgr(this, options);
        });
    };

})(jQuery); 